package com.example.xunai.service.mq;

import com.example.xunai.config.RabbitMQConfig;
import com.example.xunai.dto.request.conversation.CreateConversationRequest;
import com.example.xunai.entity.ConversationMessage;
import com.example.xunai.service.cache.CacheService;
import com.example.xunai.service.conversation.ConversationMessageService;
import com.example.xunai.service.conversation.ConversationService;
import com.example.xunai.service.user.TokenUsageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
@RequiredArgsConstructor
public class MessageSaveConsumer {

    private final ConversationService conversationService;
    private final ConversationMessageService conversationMessageService;
    private final CacheService cacheService;
    private final TokenUsageService tokenUsageService;

    @RabbitListener(queues = RabbitMQConfig.MESSAGE_SAVE_QUEUE)
    @Transactional
    public void processMessageSave(Object task) {
        log.info("开始保存消息: {}", task);

        try {
            // 从task对象中提取必要信息
            Long conversationId = getConversationIdFromTask(task);
            Long userId = getUserIdFromTask(task);
            String userMessage = getUserMessageFromTask(task);
            String aiResponse = getAiResponseFromTask(task);
            String modelType = getModelTypeFromTask(task);
            String requestId = getRequestIdFromTask(task);

            // 如果 conversationId 为 null，创建新对话
            if (conversationId == null) {
                String sessionId = "sess_" + System.currentTimeMillis();
                // 使用新的CreateConversationRequest创建对话
                CreateConversationRequest createRequest = CreateConversationRequest.of(
                        generateConversationTitle(userMessage),
                        modelType,
                        sessionId,
                        userId
                );
                var conversationResponse = conversationService.createConversation(createRequest);
                conversationId = conversationResponse.getId();
                log.info("创建新对话: {}", conversationId);
            }

            // 保存用户消息
            ConversationMessage userMessageEntity = saveMessage(
                    conversationId, "user", userMessage, null
            );

            // 保存 AI 回复
            Long aiMessageId = null;
            if (aiResponse != null && !aiResponse.trim().isEmpty()) {
                ConversationMessage aiMessage = saveMessage(
                        conversationId, "assistant", aiResponse,
                        userMessageEntity.getTurn() + 1
                );
                aiMessageId = aiMessage.getId();

                // 记录token使用 - 直接调用TokenUsageService的方法
                int inputTokens = estimateTokens(userMessage);
                int outputTokens = estimateTokens(aiResponse);

                tokenUsageService.recordTokenUsage(
                        userId, conversationId, aiMessageId, modelType,
                        inputTokens, outputTokens
                );
            }

            // 更新对话时间
            conversationService.updateConversationTime(conversationId);

            // 清除相关缓存
            cacheService.evictConversationCache(conversationId);

            log.info("消息保存完成: {}, 对话ID: {}, AI消息ID: {}, 用户ID: {}, 模型: {}",
                    requestId, conversationId, aiMessageId, userId, modelType);

        } catch (Exception e) {
            log.error("保存消息失败: {}", task, e);
        }
    }

    @RabbitListener(queues = RabbitMQConfig.MESSAGE_SAVE_QUEUE, concurrency = "3")
    @Transactional
    public void processBatchMessageSave(List<Object> tasks) {
        log.info("开始批量保存消息，数量: {}", tasks.size());

        List<ConversationMessage> allMessages = new ArrayList<>();

        for (Object task : tasks) {
            try {
                Long conversationId = getConversationIdFromTask(task);
                Long userId = getUserIdFromTask(task);
                String userMessage = getUserMessageFromTask(task);
                String aiResponse = getAiResponseFromTask(task);
                String modelType = getModelTypeFromTask(task);
                String requestId = getRequestIdFromTask(task);

                if (conversationId == null) {
                    String sessionId = "sess_" + System.currentTimeMillis();
                    // 使用新的CreateConversationRequest创建对话
                    CreateConversationRequest createRequest = CreateConversationRequest.of(
                            generateConversationTitle(userMessage),
                            modelType,
                            sessionId,
                            userId
                    );
                    var conversationResponse = conversationService.createConversation(createRequest);
                    conversationId = conversationResponse.getId();
                    log.info("批量处理中创建新对话: {}, 请求ID: {}", conversationId, requestId);
                }

                // 保存用户消息
                ConversationMessage userMessageEntity = createMessage(
                        conversationId, "user", userMessage, null
                );
                allMessages.add(userMessageEntity);

                // 保存 AI 回复
                if (aiResponse != null && !aiResponse.trim().isEmpty()) {
                    ConversationMessage aiMessage = createMessage(
                            conversationId, "assistant", aiResponse,
                            userMessageEntity.getTurn() + 1
                    );
                    allMessages.add(aiMessage);

                    // 记录token使用 - 直接调用TokenUsageService的方法
                    int inputTokens = estimateTokens(userMessage);
                    int outputTokens = estimateTokens(aiResponse);

                    tokenUsageService.recordTokenUsage(
                            userId, conversationId, aiMessage.getId(), modelType,
                            inputTokens, outputTokens
                    );
                }

                // 批量更新对话时间
                conversationService.updateConversationTime(conversationId);

                // 清除缓存
                cacheService.evictConversationCache(conversationId);

                log.debug("批量消息处理完成: {}, 对话ID: {}", requestId, conversationId);

            } catch (Exception e) {
                log.error("批量保存消息失败: {}", getRequestIdFromTask(task), e);
            }
        }

        // 批量保存所有消息
        if (!allMessages.isEmpty()) {
            conversationMessageService.saveAll(allMessages);
            log.info("批量保存消息完成，总消息数: {}", allMessages.size());
        }
    }

    // 从task对象中提取信息的方法
    private Long getConversationIdFromTask(Object task) {
        if (task instanceof Map) {
            Object conversationId = ((Map<?, ?>) task).get("conversationId");
            if (conversationId instanceof Long) {
                return (Long) conversationId;
            } else if (conversationId instanceof Integer) {
                return ((Integer) conversationId).longValue();
            } else if (conversationId instanceof String) {
                try {
                    return Long.parseLong((String) conversationId);
                } catch (NumberFormatException e) {
                    return null;
                }
            }
        }
        return null;
    }

    private Long getUserIdFromTask(Object task) {
        if (task instanceof Map) {
            Object userId = ((Map<?, ?>) task).get("userId");
            if (userId instanceof Long) {
                return (Long) userId;
            } else if (userId instanceof Integer) {
                return ((Integer) userId).longValue();
            } else if (userId instanceof String) {
                try {
                    return Long.parseLong((String) userId);
                } catch (NumberFormatException e) {
                    return 1L;
                }
            }
        }
        return 1L;
    }

    private String getUserMessageFromTask(Object task) {
        if (task instanceof Map) {
            Object userMessage = ((Map<?, ?>) task).get("userMessage");
            if (userMessage instanceof String) {
                return (String) userMessage;
            }
        }
        return "";
    }

    private String getAiResponseFromTask(Object task) {
        if (task instanceof Map) {
            Object aiResponse = ((Map<?, ?>) task).get("aiResponse");
            if (aiResponse instanceof String) {
                return (String) aiResponse;
            }
        }
        return "";
    }

    private String getModelTypeFromTask(Object task) {
        if (task instanceof Map) {
            Object modelType = ((Map<?, ?>) task).get("modelType");
            if (modelType instanceof String) {
                return (String) modelType;
            }
        }
        return "deepseek";
    }

    private String getRequestIdFromTask(Object task) {
        if (task instanceof Map) {
            Object requestId = ((Map<?, ?>) task).get("requestId");
            if (requestId instanceof String) {
                return (String) requestId;
            }
        }
        return String.valueOf(System.currentTimeMillis());
    }

    private Integer getInputTokensFromTask(Object task) {
        if (task instanceof Map) {
            Object inputTokens = ((Map<?, ?>) task).get("inputTokens");
            if (inputTokens instanceof Integer) {
                return (Integer) inputTokens;
            }
        }
        return null;
    }

    private Integer getOutputTokensFromTask(Object task) {
        if (task instanceof Map) {
            Object outputTokens = ((Map<?, ?>) task).get("outputTokens");
            if (outputTokens instanceof Integer) {
                return (Integer) outputTokens;
            }
        }
        return null;
    }

    private ConversationMessage saveMessage(Long conversationId, String role,
                                            String content, Integer turn) {
        ConversationMessage message = createMessage(conversationId, role, content, turn);
        return conversationMessageService.saveMessage(message);
    }

    private ConversationMessage createMessage(Long conversationId, String role,
                                              String content, Integer turn) {
        ConversationMessage message = new ConversationMessage();
        message.setConversationId(conversationId);
        message.setRole(ConversationMessage.MessageRole.valueOf(role));
        message.setContent(content);
        message.setCreateTime(LocalDateTime.now());

        if (turn == null) {
            Integer lastTurn = conversationMessageService.getLastTurnByConversationId(conversationId);
            message.setTurn(lastTurn != null ? lastTurn + 1 : 1);
        } else {
            message.setTurn(turn);
        }

        return message;
    }

    /**
     * 估算文本的token数量
     */
    private int estimateTokens(String text) {
        if (text == null || text.isEmpty()) return 0;

        int chineseChars = 0;
        int englishChars = 0;

        for (char c : text.toCharArray()) {
            if (Character.toString(c).matches("[\\u4e00-\\u9fa5]")) {
                chineseChars++;
            } else if (Character.isLetterOrDigit(c) || Character.isWhitespace(c)) {
                englishChars++;
            } else {
                englishChars++;
            }
        }

        int estimatedTokens = (int) Math.ceil(chineseChars / 1.5) + (int) Math.ceil(englishChars / 3.0);
        return Math.max(1, estimatedTokens);
    }

    private String generateConversationTitle(String userMessage) {
        if (userMessage == null || userMessage.trim().isEmpty()) {
            return "新对话";
        }
        String title = userMessage.trim();
        return title.length() > 20 ? title.substring(0, 20) + "..." : title;
    }
}